package io.sunny.platform.ai.deepseek.service;

import io.github.pigmesh.ai.deepseek.core.DeepSeekClient;
import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionRequest;
import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionResponse;
import io.sunny.platform.ai.deepseek.config.DeepSeekConfigProperties;
import io.sunny.platform.ai.deepseek.model.UserInput;
import io.sunny.platform.ai.deepseek.session.DialogSession;
import io.sunny.platform.ai.deepseek.session.DialogSession.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author SUNNY
 * @Date 2025/11/29 22:44
 * @PackageName: io.sunny.platform.ai.deepseek.service
 * @Description: 智能对话系统（保持上下文的多轮对话）
 * @Version 1.0
 */
@Slf4j
@Service
public class IntelligentDialogService {
    private final DeepSeekClient deepSeekClient;
    private final Map<String, DialogSession> sessionStore = new ConcurrentHashMap<>();
    private final int MAX_HISTORY_LENGTH = 20;  // 最大历史记录长度

    public IntelligentDialogService(DeepSeekConfigProperties config) {
        this.deepSeekClient = new DeepSeekClient.Builder()
                .openAiApiKey(config.getKey())
                .baseUrl(config.getBaseUrl())
                .connectTimeout(config.getTimeout().getConnect())
                .readTimeout(config.getTimeout().getRead())
                .build();
    }

    public String handleUserInput(String sessionId, UserInput input) {
        // 获取或创建会话
        DialogSession session = sessionStore.computeIfAbsent(sessionId,
                id -> new DialogSession(id, new LinkedList<>()));

        // 添加上下文信息
        Message userMessage = enhanceWithContext(input, session);
        session.addMessage(userMessage);

        // 调用AI服务
        ChatCompletionResponse response = generateAIResponse(session.getMessages());
        String responseContent = response != null ? response.content() : "对话服务暂时不可用";

        // 保存AI响应
        Message assistantMessage = new Message("assistant", responseContent, System.currentTimeMillis());
        session.addMessage(assistantMessage);

        // 清理过期历史
        trimSessionHistory(session);
        session.setLastUpdateTime(System.currentTimeMillis());

        return responseContent;
    }

    private Message enhanceWithContext(UserInput input, DialogSession session) {
        String enhanceContext = input.getContent();

        // 添加上下文关联信息
        if (!session.getMessages().isEmpty()) {
            enhanceContext = "对话上下文：\n" +
                    session.getRecentContent() + "\n\n当前问题：" + input.getContent();
        }

        // 添加领域知识
        if (input.getDomain() != null) {
            enhanceContext = "领域：" + input.getDomain() + "\n" + enhanceContext;
        }

        return new Message("user", enhanceContext, System.currentTimeMillis());
    }

    private ChatCompletionResponse generateAIResponse(List<Message> messages) {
        try {
            ChatCompletionRequest request = ChatCompletionRequest.builder()
                    .messages((io.github.pigmesh.ai.deepseek.core.chat.Message) messages)
                    .temperature(0.7)            // 创建性程度
                    .maxCompletionTokens(1024)   // 最大生成长度
                    .topP(0.9)                   // 核采样参数
                    .build();
            return deepSeekClient.chatCompletion(request).execute();
        } catch (Exception e) {
            log.error("AI对话生成失败", e);
            return null;
        }
    }

    private void trimSessionHistory(DialogSession session) {
        if (session.getMessageCount() > MAX_HISTORY_LENGTH) {
            session.trimMessages(MAX_HISTORY_LENGTH / 2);  // 保留最近的一半记录
        }
    }

    /**
     * 会话清理
     */
    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void cleanupExpiredSessions() {
        long cutoffTime = System.currentTimeMillis() - 30 * 60 * 1000;   // 30分钟前

        sessionStore.entrySet().removeIf(entry -> entry.getValue().getLastUpdateTime() < cutoffTime);
    }
}
